﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsumeAndProduceFactory
{
    public class Producer: IProducer
    {
        private Status m_workStatus;
        private WareHouse wareHouse;
        private Thread m_workThread;
        private ManualResetEvent manualEvent;
        public event FactoryEventHandler Producing;

        //定义了同步变量
        public Producer(WareHouse sharedLocation, FactoryEventHandler producing)
        {
            wareHouse = sharedLocation;
            this.Producing = producing;
            manualEvent = new ManualResetEvent(false);
        }

        //此处构造函数的作用是在启动类中调用Producer的时候,把启动类中定义的sharedLocation传过来


        public void produce()//定义生产过程
        {
            while (!m_workStatus.Equals(Status.STATUS_STOP))
            {
                if (m_workStatus.Equals(Status.STATUS_PAUSE))
                {
                    manualEvent.WaitOne();

                }
                // 生产事件
                List<Object> list = new List<Object>();
                FactoryEventArgs args = new FactoryEventArgs(list, FactoryMsg.ProducingOk);
                if (Producing != null)
                {
                    Producing(this, args);
                }

                if (args.Msg != null && args.Msg == FactoryMsg.ProducingFinished)
                {
                    m_workStatus = Status.STATUS_STOP;
                    wareHouse.Flush = true;
                }
                else if (args.Products != null)
                {
                    list = (List<Object>)args.Products;
                    // 放入
                    wareHouse.pubGoods(list);
                }
            }
        }

        public void start()
        {
            m_workStatus = Status.STATUS_WORKING;
            m_workThread = new Thread(new ThreadStart(produce));
            m_workThread.IsBackground = true;
            m_workThread.Start();
        }

        public void pause()
        {
            manualEvent.Reset();
            m_workStatus = Status.STATUS_PAUSE;
        }

        public void resume()
        {
            manualEvent.Set();
            m_workStatus = Status.STATUS_WORKING;
        }

        public void stop()
        {
            m_workStatus = Status.STATUS_STOP;
        }
        public void stopImmediately()
        {
            m_workStatus = Status.STATUS_STOP;
            m_workThread.Abort();
        }
    }
}
